from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

from oauth.models import OAuthQQUser
from users.models import User
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from django.conf import settings


class QQAuthUserSerializer(serializers.ModelSerializer):
    sms_code = serializers.CharField(label='短信验证码', max_length=6, write_only=True)
    access_token = serializers.CharField(write_only=True)
    token = serializers.CharField(read_only=True)  # 添加token字段
    user_id=serializers.IntegerField(read_only=True)
    class Meta:
        model = User
        fields = ('mobile', 'password', 'token', 'username', 'sms_code', 'access_token', 'user_id')

        extra_kwargs = {
            'username': {
                'read_only': True,
                'min_length': 5,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许5-20个字符的用户名',
                    'max_length': '仅允许5-20个字符的用户名',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许8-20个字符的密码',
                    'max_length': '仅允许8-20个字符的密码',
                }
            }
        }

    def validate(self, attrs):

        # 验证access——token有效性
        # 解密
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(attrs['access_token'].encode())
        except:
            raise serializers.ValidationError('错误的token值')
        # 判断是否access——token是否失效
        openid = data.get('openid')

        if not openid:
            raise serializers.ValidationError('token值失效')
        # attrs中添加openid
        attrs['openid'] = openid

        # 校验短信验证码
        strict_redis = get_redis_connection('sms_codes')
        mobile = attrs.get('mobile')
        # 正确的短信验证码
        real_sms_code = strict_redis.get('sms_%s' % mobile)  # bytes
        sms_code = attrs.get('sms_code')

        if real_sms_code is None:  # 已经超过了过期时间
            raise serializers.ValidationError('无效的短信验证码')
        # 用户输入的短信验证码
        if sms_code != real_sms_code.decode():
            raise serializers.ValidationError('短信验证码不正确')

        # 用户验证
        # 通手机号判断所对应的用户是否存在
        try:
            user = User.objects.get(mobile=attrs['mobile'])
        except:

            return attrs

        else:
            if not user.check_password(attrs['password']):
                raise serializers.ValidationError('密码错误')
            # attrs中添加user
            attrs['user2'] = user
            return attrs

    # 绑定保存
    def create(self, validated_data):
        # 判断用户是否存在
        user = validated_data.get('user2', None)
        # user = User.objects.get(mobile=validated_data['mobile'])

        if user is None:
            # 如过用户不存在,创建新用户
            user = User.objects.create_user(username=validated_data['mobile'], password=validated_data['password'],
                                            mobile=validated_data['mobile'])
        # 绑定openid
        OAuthQQUser.objects.create(user=user, openid=validated_data['openid'])

        # 生成token值
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 添加token
        user.token = token
        user.user_id=user.id

        return user

